Open up web.config and add the following to appConfig:
<add key="UnitSTS:FederationMetadataLocation" value="https://codev1.dot.state.fl.us/fdot.sts/federationmetadata/2007-06/federationmetadata.xml" />
<add key="UnitSTS:Realm" value="https://yoururlhere/" />
<add key="UnitSTS:AudienceUri" value="https://yoururlhere/" />
<add key="UnitSTS:SigningThumb" value="9748D73D42FF7CBD1C3CCD6FC7B2DFABF3AB6FD6" />
<add key="UnitSTS:EncryptionThumb" value="9748D73D42FF7CBD1C3CCD6FC7B2DFABF3AB6FD6" />
<add key="UnitSTS:Issuer" value="https://codev1.dot.state.fl.us/FDOT.STS/securitytoken/issue" />
Create a class called Saml2SecurityTokenHandlerEx:
public class Saml2SecurityTokenHandlerEx : Saml2SecurityTokenHandler, ISecurityTokenValidator
{
public override bool CanReadToken(string securityToken)
{
using (var sreader = new StringReader(securityToken))
{
using (var xreader = XmlReader.Create(sreader))
{
return base.CanReadToken(xreader);
}
}
}
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters,
out SecurityToken validatedToken)
{
using (var sreader = new StringReader(securityToken))
{
using (var xreader = XmlReader.Create(sreader))
{
validatedToken = ReadToken(xreader, Configuration.ServiceTokenResolver);
return new ClaimsPrincipal(ValidateToken(validatedToken));
}
}
}
public int MaximumTokenSizeInBytes { get; set; }
}
Create a class called EncryptedSecurityTokenHandlerEx:
public class EncryptedSecurityTokenHandlerEx : EncryptedSecurityTokenHandler, ISecurityTokenValidator
{
public EncryptedSecurityTokenHandlerEx(SecurityTokenResolver securityTokenResolver)
{
Configuration = new SecurityTokenHandlerConfiguration
{
ServiceTokenResolver = securityTokenResolver
};
}
public override bool CanReadToken(string securityToken)
{
using (var stringreader = new StringReader(securityToken))
{
using (var xreader = new XmlTextReader(stringreader))
{
return base.CanReadToken(xreader);
}
}
}
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters,
out SecurityToken validatedToken)
{
using (var stringreader = new StringReader(securityToken))
{
using (var xreader = new XmlTextReader(stringreader))
{
validatedToken = ReadToken(xreader, Configuration.ServiceTokenResolver);
}
}
return ContainingCollection != null ? new ClaimsPrincipal(ContainingCollection.ValidateToken(validatedToken)) :
new ClaimsPrincipal(base.ValidateToken(validatedToken));
}
public int MaximumTokenSizeInBytes { get; set; }
}
Open up Startup.Auth:
public partial class Startup
{
private static string unitRealm = ConfigurationManager.AppSettings["UnitSTS:Realm"];
private static string unitStsMetadata = ConfigurationManager.AppSettings["UnitSTS:FederationMetadataLocation"];
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieSecure = CookieSecureOption.Always,
ExpireTimeSpan = new TimeSpan(0, 5, 0, 0),
CookieHttpOnly = true,
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
Provider = new CookieAuthenticationProvider()
{
OnApplyRedirect = ctx =>
{
var response = ctx.Response;
response.Redirect(ctx.RedirectUri);
}
}
});
var tokenHandlers = MakeTokenHandlerCollection();
var stsOptions = MakeAuthenticationOptions(tokenHandlers);
app.UseWsFederationAuthentication(stsOptions);
app.UseStageMarker(PipelineStage.Authenticate);
}
private WsFederationAuthenticationOptions MakeAuthenticationOptions(SecurityTokenHandlerCollection tokenHandlerCollection)
{
var wsEvents = new WsFederationAuthenticationNotifications();
wsEvents.AuthenticationFailed += AuthenticationFailed;
wsEvents.RedirectToIdentityProvider += RedirectToIdentityProvider;
wsEvents.SecurityTokenValidated += SecurityTokenValidated;
wsEvents.SecurityTokenReceived += SecurityTokenReceived;
return new WsFederationAuthenticationOptions
{
Notifications = wsEvents,
SecurityTokenHandlers = tokenHandlerCollection,
MetadataAddress = unitStsMetadata,
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
// Wreply = $"{unitRealm}api/login/logincallback/",
Wtrealm = unitRealm,
TokenValidationParameters = new TokenValidationParameters
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
ValidAudience = unitRealm
}
};
}
private Task SecurityTokenReceived(SecurityTokenReceivedNotification<WsFederationMessage, WsFederationAuthenticationOptions> securityTokenReceivedNotification)
{
return Task.FromResult(0);
}
private SecurityTokenHandlerCollection MakeTokenHandlerCollection()
{
var audienceRestriction = new AudienceRestriction(AudienceUriMode.Always);
audienceRestriction.AllowedAudienceUris.Add(new Uri(unitRealm));
var issuerRegistry = new ConfigurationBasedIssuerNameRegistry();
issuerRegistry.AddTrustedIssuer(ConfigurationManager.AppSettings["UnitSTS:SigningThumb"], ConfigurationManager.AppSettings["UnitSTS:Issuer"]);
var tokenResolver = new X509CertificateStoreTokenResolver(StoreName.My, StoreLocation.LocalMachine);
return new SecurityTokenHandlerCollection
{
new EncryptedSecurityTokenHandlerEx(tokenResolver),
new Saml2SecurityTokenHandlerEx
{
CertificateValidator = X509CertificateValidator.None,
Configuration = new SecurityTokenHandlerConfiguration
{
AudienceRestriction = audienceRestriction,
IssuerNameRegistry = issuerRegistry,
ServiceTokenResolver = tokenResolver
}
}
};
}
private Task SecurityTokenValidated(SecurityTokenValidatedNotification<WsFederationMessage, WsFederationAuthenticationOptions> securityTokenValidatedNotification)
{
var redirectUri = new Uri(securityTokenValidatedNotification.AuthenticationTicket.Properties.RedirectUri, UriKind.RelativeOrAbsolute);
if (redirectUri.IsAbsoluteUri)
{
securityTokenValidatedNotification.AuthenticationTicket.Properties.RedirectUri = redirectUri.PathAndQuery;
}
// ApplyClaims(securityTokenValidatedNotification.AuthenticationTicket.Identity);
return Task.FromResult(0);
}
private Task RedirectToIdentityProvider(RedirectToIdentityProviderNotification<WsFederationMessage,
WsFederationAuthenticationOptions> redirectToIdentityProviderNotification)
{
if (IsAjaxRequest(redirectToIdentityProviderNotification.Request))
{
redirectToIdentityProviderNotification.OwinContext.Response.StatusCode = 401;
redirectToIdentityProviderNotification.HandleResponse();
}
if (redirectToIdentityProviderNotification.OwinContext.Response.StatusCode == 401 &&
redirectToIdentityProviderNotification.OwinContext.Authentication.User.Identity.IsAuthenticated)
{
redirectToIdentityProviderNotification.OwinContext.Response.StatusCode = 403;
redirectToIdentityProviderNotification.HandleResponse();
}
return Task.FromResult(0);
}
private Task AuthenticationFailed(AuthenticationFailedNotification<WsFederationMessage, WsFederationAuthenticationOptions> authenticationFailedNotification)
{
if (IsAjaxRequest(authenticationFailedNotification.Request))
{
authenticationFailedNotification.HandleResponse();
}
return Task.Delay(0);
}
private static bool IsAjaxRequest(IOwinRequest request)
{
IReadableStringCollection query = request.Query;
if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
{
return true;
}
IHeaderDictionary headers = request.Headers;
return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}
}